#include "Shape.h"

void Shape::init()
{
	dm = SDM_DYNAMIC;
	ci = 0;
	cv = 0;
	IB = 0;
	VB = 0;
	primtype = GL_TRIANGLES;
	vertices = 0;
	indices = 0;
}

Shape::Shape()
{
	init();
}

Shape::Shape(int ci_,int cv_)
{
	init();

	ci = ci_;
	cv = cv_;

	vertices = new Vertex[cv];
	indices = new unsigned short int [ci];
}

Shape::Shape(const char* filename)
{
	init();

	Load(filename);
	DrawMode(SDM_STATIC);
}

Shape::~Shape()
{
}

void Shape::DrawMode(ShapeDrawMode dm_)
{
	if(dm!=dm_)
	{
		if(dm_ == SDM_STATIC)
			MakeVBO();
	}

	dm = dm_;
}

void Shape::SetIndex(int i,int index)
{
	if(i<0 || i>ci-1)
		return;

	if(index<0 || index>cv-1)
		return;

	indices[i] = index;
}

void Shape::SetVertexPos(int i,float x,float y)
{
	if(i<0 || i>cv-1)
		return;

	vertices[i].x = x;
	vertices[i].y = y;
	vertices[i].z = 0;
}

void Shape::SetVertexUV(int i,float u,float v)
{
	if(i<0 || i>cv-1)
		return;

	vertices[i].u = u;
	vertices[i].v = v;
}

void Shape::SetVertexColor(int i,unsigned char r,unsigned char g,unsigned char b,unsigned char a = 255)
{
	if(i<0 || i>cv-1)
		return;

	vertices[i].r = r;
	vertices[i].g = g;
	vertices[i].b = b;
	vertices[i].a = a;
}

void Shape::Draw(float x, float y)
{
	glPushMatrix();
	glTranslatef(x,y,0);

	Draw();


	glPopMatrix();
}


void Shape::Draw()
{
	if(dm == SDM_STATIC)
	{
		if(Entts::last_indexB!=IB)
		{
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,IB);	
			//debug::Log<<"bbind IB"<<std::endl;
			Entts::last_indexB=IB;
		}

		if(Entts::last_vertexB!=VB)
		{
			glBindBuffer(GL_ARRAY_BUFFER, VB );

			/*
			glTexCoordPointer(2,GL_FLOAT,20,(void*)(__int64)0);
			glColorPointer(4,GL_UNSIGNED_BYTE,20,(void*)(__int64)8);
			glVertexPointer(2,GL_FLOAT,20,(void*)(__int64)12);
			*/


			//debug::Log<<"bbind VB"<<std::endl;
			glInterleavedArrays(GL_T2F_C4UB_V3F,0,0);
			Entts::last_vertexB=VB;
		}

		glDrawRangeElements(primtype,0,ci-1,ci,GL_UNSIGNED_SHORT, 0);

	}
	else
	{
		glBegin(primtype);
		//debug::Log<<"ci = "<<ci<<std::endl;

		for(int i=0;i<ci;++i)
		{
			Vertex v = vertices[indices[i]];
			
			glColor4ub(v.r,v.g,v.b,v.a);
			glVertex2f(v.x,v.y);

		}
		glEnd();
	}
}

void Shape::MakeVBO()
{
	if(IB)
		glDeleteBuffers(1,&IB);

	if(VB)
		glDeleteBuffers(1,&VB);

	glGenBuffers(1,&IB);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,IB);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER,ci*sizeof(unsigned short int),indices,GL_STATIC_DRAW);

	glGenBuffers(1,&VB);
	glBindBuffer(GL_ARRAY_BUFFER,VB);
	glBufferData(GL_ARRAY_BUFFER,cv*sizeof(Vertex),vertices,GL_STATIC_DRAW);
}

void Shape::Color(unsigned char r,unsigned char g,unsigned char b,unsigned char a = 255)
{
	for(int i=0;i<cv;++i)
	{
		vertices[i].r = r;
		vertices[i].g = g;
		vertices[i].b = b;
		vertices[i].a = a;
	}
}

void Shape::SetPrimType(unsigned int pt)
{
	primtype = pt;
}

void Shape::Load(const char *filename)
{
	FILE *f = 0;
	errno_t err;

	err = fopen_s(&f,filename,"rb");

	if(err==0)
	{
		int version = 0;
		fread(&version,4,1,f); //version number
		if(version==1)
		{
			fread(&primtype,4,1,f);

			fread(&ci,4,1,f);
			fread(&cv,4,1,f);

			resize(ci,cv);

			fread(indices,sizeof(unsigned short int),ci,f);
			fread(vertices,sizeof(Vertex),cv,f);
		}

		fclose(f);
	}
	else
	{
		debug::Log<<"shape load failed! filename:"<<filename<<std::endl;
	}

	if(dm == SDM_STATIC)
		MakeVBO();

}

void Shape::Save(const char *filename)
{
	FILE *f = 0;
	errno_t err;

	err = fopen_s(&f,filename,"wb");

	if(err==0)
	{
		int version = 1;
		fwrite(&version,4,1,f); //version number

		fwrite(&primtype,4,1,f);

		fwrite(&ci,4,1,f);
		fwrite(&cv,4,1,f);

		fwrite(indices,sizeof(unsigned short int),ci,f);
		fwrite(vertices,sizeof(Vertex),cv,f);

		fclose(f);
	}
	else
	{
		debug::Log<<"shape load failed! filename:"<<filename<<std::endl;
	}
}

void Shape::resize(int ci,int cv)
{
	if(ci<0)
		return;

	if(cv<0 || cv>65535)
		return;

	if(vertices)
		delete[] vertices;

	if(indices)
		delete[] indices;

	indices = new unsigned short int[ci];
	vertices = new Vertex[cv];
}